import SwiftSyntax

/// A declaration that can declare inheritance.
///
/// The declaration can conform to protocols or inherit classes.
protocol InheritableDeclSyntax: DeclSyntaxProtocol {
    /// The type of this declaration.
    var currentType: TypeSyntax { get }
    /// Modifiers like `public` that are attached to this declaration.
    var modifiers: DeclModifierListSyntax { get }
    /// Attributes that are attached to this declaration.
    var attributes: AttributeListSyntax { get }
    /// The inheritance clause describing one or more conformances
    /// for this declaration.
    var inheritanceClause: InheritanceClauseSyntax? { get }
    /// The `where` clause that applies to the generic parameters
    /// of this declaration.
    var genericWhereClause: GenericWhereClauseSyntax? { get }
    /// The members of the declaration.
    ///
    /// Because extension declarations may declare additional members
    /// the contents of this member block isn't guaranteed to be a complete
    /// list of members for this type.
    var memberBlock: MemberBlockSyntax { get }
}

/// An `InheritableDeclSyntax` that represents a type.
///
/// Represents a type definition declaration.
protocol InheritableTypeDeclSyntax: InheritableDeclSyntax {
    /// Declares the name of this declaration.
    ///
    /// If the name matches a reserved keyword use backticks to escape it.
    ///
    /// ### Tokens
    ///
    /// For syntax trees generated by the parser, this is guaranteed to be `<identifier>`.
    var name: TokenSyntax { get }
    /// The generic parameters, if any, of this declaration.
    var genericParameterClause: GenericParameterClauseSyntax? { get }
}

extension InheritableTypeDeclSyntax {
    /// The type of this declaration.
    ///
    /// Represents the `name` of this declaration.
    var currentType: TypeSyntax { TypeSyntax(IdentifierTypeSyntax(name: name)) }
}

extension StructDeclSyntax: InheritableTypeDeclSyntax {}
extension EnumDeclSyntax: InheritableTypeDeclSyntax {}
extension ClassDeclSyntax: InheritableTypeDeclSyntax {}
extension ActorDeclSyntax: InheritableTypeDeclSyntax {}

extension ExtensionDeclSyntax: InheritableDeclSyntax {
    /// The type of this declaration.
    ///
    /// Represents the type that is extended by this declaration.
    var currentType: TypeSyntax { extendedType }
}
